#coding=utf-8
# !/usr/bin/python
# -*- coding: utf-8 -*-

import numpy as np
from data_devmatain import * # 用户参数

pack_sta_req_sfcnt = 0

MAITAIN_DEVINFO_SET = 0x51 # 设备信息配置 */ 
MAITAIN_BITCFG_SET = 0x54 # /* BIT配置 */
MAITAIN_DEVCFG_SET = 0x55 #/* 参数配置 */ 
MAITAIN_USERCFG_SET = 0x56 # /* 用户参数 */
MAITAIN_DEVLOG_READ = 0x57 # /* 设备日志读取 */
MAITAIN_DETECTION = 0X58 # /* 部件检测 */
MAITAIN_OTA = 0x59 #/* 在线升级 */

def GetCheckWord(p, length) :
    i = 0
    Xor_Temp = 0
    Sum_Temp = 0
    CheckWord = 0;
    # 异或
    for i in range(length - 2):
       Xor_Temp = (Xor_Temp ^ (p[ i ] & 0xff))&0xff
    
    # 和 
    for i in range(length - 2):
       Sum_Temp = (Sum_Temp + (p[ i ] & 0xff))&0xff
    
    Sum_Temp = Sum_Temp + Xor_Temp;
    # 0-前面所有字节之和 
    Sum_Temp =  (0 - (Sum_Temp & 0xff))&0xffff; # 反码+1
    CheckWord = ((Sum_Temp << 8) | Xor_Temp)&0xffff
    return CheckWord;

class c_devsta:
    def __init__(self):
        self.frame_cnt = 0 # 3 发送帧计数
        self.syspart = 0 # 5 系统/组件
        self.type = 0 # 6 帧类型
        self.dzyt_mode = 1 # 7 氧调工作模式
        self.dzyt_fault = 0 # 8 氧调故障状态
        self.dzyt_weihu = 0 # 9 氧调维护告警
        self.sysweihu_option_back = 0 # 10 系统维护反馈 */
        self.dzyt_poweron = 0 # 11 氧调启/停状态 */
        self.pe_calib_back = 0 # 12 压差传感器校准反馈 */
        self.panel_gmode_sw = 0 # 13 供氧开关状态
        self.panel_wmode_sw = 0 # 14 模式开关状态
        self.sample_pe = 0 # 15 呼吸腔压差
        self.emerg_press = 0 # 17 应急氧压力
        self.remote_pwon = 0 # 21 氧调远程命令状态
        self.detect_option = 0 # 22 部件检测选项
        self.dval1_current = 0 # 40 肺式电磁阀1电流
        self.eval_current = 0 # 46 应急电磁阀电流
        self.sf_version = 0 # 52 软件版本信息
        self.sf_date = 0 # 54 软件日期信息 */
        self.cfg_crc16 = 0 # 56 配置校验值

        self.c_matain = c_devmatain() # 部件检测

    def pack_frame_head(self):
        global pack_sta_req_sfcnt
        data = np.zeros(64, dtype=np.uint8)
        data[0] = 0xAA # /* 0 帧头1 */
        data[1] = 0x55 # /* 1 帧头2 */
        data[2] = 64 # /* 2 帧长度 */
        data[3] = pack_sta_req_sfcnt # /* 3 发送帧计数 */
        pack_sta_req_sfcnt = (pack_sta_req_sfcnt + 1)&0xff
        data[5] = 0x12 # /* 5 系统/组件 */
        data[6] = 1 # /* 6 帧类型 */
        return data

     def pack_frame_tail(self, a):
        a = np.zeros(64, dtype=np.uint8)
        verify = GetCheckWord(a, 64)
        a[62] = verify & 0xff
        a[63] = verify >> 8
        return a    

        
    def decode_sta(self, a):
        self.syspart = a[5] # 5 系统/组件
        self.type = a[6] # 6 帧类型
        self.frame_cnt = a[3] # 3 发送帧计数
        self.dzyt_mode = a[7] # 7 氧调工作模式
        self.dzyt_fault = a[8] # 8 氧调故障状态
        self.dzyt_weihu = a[9] # 9 氧调维护告警
        self.sysweihu_option_back = a[10] # 10 系统维护反馈 */
        self.dzyt_poweron = a[11] # 11 氧调启/停状态 */
        self.pe_calib_back = a[12] # 12 压差传感器校准反馈 */
        self.panel_gmode_sw = a[13] # 13 供氧开关状态
        self.panel_wmode_sw = a[14] # 14 模式开关状态
        self.sample_pe = a[15] + (a[16] << 8)   # 15 呼吸腔压差
        self.emerg_press = a[17] + (a[18] << 8) # 17 应急氧压力
        self.remote_pwon = a[15] # 21 氧调远程命令状态
        self.detect_option = a[15] # 22 部件检测选项
        self.dval1_current = a[40] + (a[41] << 8) # 40 肺式电磁阀1电流
        self.eval_current = a[46] + (a[47] << 8) # 46 应急电磁阀电流
        self.sf_version = (a[52] << 8) + a[53] # 52 软件版本信息
        self.sf_date = (a[54] << 8) + a[55] # 54 软件日期信息 */
        self.cfg_crc16 = (a[56] << 8) + a[57] # 56 配置校验值 
     
   
    def find_head(self, a):
        for i in range(len(a) - 63):
            if a[i] == 0xAA and a[i+1] == 0x55:
                return a[i : i + 64]
        return []

    def decode(self, data):
        ret = 0
        data = self.find_head(data)
        if len(data) != 64 :
            return -1
        verify1 = GetCheckWord(data, 64)
        verify2 = data[62] + (data[63] << 8)
        if verify1 != verify2:
            print("verify err: {:0>4x}/{:0>4x}".format(verify1, verify2))
            return -1
        #else:
            #print("verify ok: {:0>4x}/{:0>4x}".format(verify1, verify2))
        
        type = data[6]
        if 1 == type:
            self.decode_sta(data)
            ret = 1
        return ret


    def str_dzyt_mode(self):
        cstr = ["未定义", # 0 未定义
            "待机", # 1 待机模式 
            "肺式模式", # 2 肺式供氧模式 
            "未定义",  # 3 未定义 
            "连续模式", # 4连续供氧模式 
            "未定义", # 5 未定义 
            "应急模式", # 6 应急模式 
            "待机",  # 7 系统维护模式 
            "未定义"]
        return cstr[self.dzyt_mode]
    def str_dzyt_fault(self):
        cstr = ["待机", "肺式模式"]
        return cstr[self.dzyt_mode]
    def str_dzyt_weihu(self):
        cstr = ["待机", "肺式模式"]
        return cstr[self.dzyt_mode]    
    def frame_pares_devsta(self):
        print("frame_pares_devsta")

    def frame_pares_devcfg(self):
        print("frame_pares_devcfg")

